#include <stdio.h>
#include "line.h"
#include "math.h"
/*-<==>-----------------------------------------------------------------
/ Builds a default empty line
/----------------------------------------------------------------------*/
CLine:: CLine() : loc(0,0,0), dir (1,0,0), color(0,0,0), level(0), t(-1e6), obj(NULL) {
}

/*-<==>-----------------------------------------------------------------
/ Builds a line with specific loc and direction
/----------------------------------------------------------------------*/
CLine::CLine (const VECTOR &nloc, const VECTOR &ndir, int nlevel) : loc (nloc), dir (ndir), color(0,0,0), level (nlevel), t(-1e6), obj(NULL) {
  dir.normalize();
}

/*-<==>-----------------------------------------------------------------
/ 
/----------------------------------------------------------------------*/
CLine CLine::getReflected(const VECTOR &nloc, const VECTOR &normal) {
	VECTOR norm;
  
	if(normal.dot(-dir) < 0)
		norm = -normal;
	else
		norm = normal;
//compute the direction of the reflected line
  SCALAR NdotDir = -norm.dot(dir);
  VECTOR reflectedRayDir = (2 * NdotDir * norm) + dir;
  return CLine( nloc, reflectedRayDir );
}
/*-<==>-----------------------------------------------------------------
/ 
/----------------------------------------------------------------------*/
CLine CLine::getRefracted(SCALAR nI, SCALAR nT , VECTOR &hitLoc,  const VECTOR &normal) {
	VECTOR norm;
	if(normal.dot(dir) > 0)
		norm = -normal;
	else
		norm = normal;
//compute the direction of the refracted line
	SCALAR NdotI = norm.dot(-dir);
	SCALAR sinI = sqrt(1 - NdotI*NdotI);
	SCALAR cosT = sqrt(1 - nI*nI/(nT*nT)*sinI*sinI);
	VECTOR t = -cosT*norm -(nI/nT)*(-dir - cosT*norm);
	t.normalize();
	return CLine(hitLoc, t);
}



/*-<==>-----------------------------------------------------------------
/ 
/----------------------------------------------------------------------*/
VECTOR CLine::getIntersection() const {
  return loc + (dir*t);
}

/*-<==>-----------------------------------------------------------------
/ return current recursion level 
/----------------------------------------------------------------------*/
int CLine::getLevel() const {
  return level;
}

/*-<==>-----------------------------------------------------------------
/ add a color amount to color of this line
/----------------------------------------------------------------------*/
void CLine::addColor(const VECTOR &amount) {
  color += amount;
}

void CLine::addLevel(int levels) {
  level+=levels;
}
